package com.marsrover;

import java.util.Scanner;
import java.util.concurrent.Callable;


/**
 * The main class of this project, take charge of creating and launching rovers.
 */
public class NASA {
	public static void main(String[] args) throws Exception {
		final Scanner scanner = new Scanner(System.in);

		print("Please input the upper-right coordinates of the plateau. The format like '5 5'.");

		final RoverManager roverManager = (RoverManager) reenter(new Callable() {
			@Override
			public Object call() throws Exception {
				return RoverManager.createRectangularPlateauRoverManager(scanner.nextLine());
			}
		});

		boolean isContinueBuildRover = true;
		while (isContinueBuildRover) {
			print("Please input the initial position and direction. The format like '1 2 N'.");

			reenter(new Callable() {
				@Override
				public Object call() throws Exception {
					roverManager.buildRover(scanner.nextLine());
					return null;
				}
			});

			print("Please input the commands. The format like 'LLLMMMRRR'.");

			reenter(new Callable() {
				@Override
				public Object call() throws Exception {
					roverManager.sendCommands(scanner.nextLine());
					return null;
				}
			});

			roverManager.launchRover();

			print("Continue to build and launch the rover? (y/n)");
			String yesOrNo = scanner.nextLine();
			if (!yesOrNo.equalsIgnoreCase("n") && !yesOrNo.equalsIgnoreCase("y")) {
				print("Please input y/n");
				yesOrNo = scanner.nextLine();
			}
			if (yesOrNo.equalsIgnoreCase("n")) isContinueBuildRover = false;
		}

		print("Report the final positions and directions of all launched rovers.");
		roverManager.reportLaunchedRoversInfo();
	}

	private static void print(Object obj) {
		System.out.println(obj);
	}

	private static Object reenter(Callable callable) {
		Object result = null;

		boolean isWrong;
		do {
			try {
				result = callable.call();
				isWrong = false;
			} catch (FormatException e) {
				print(e.getMessage());
				isWrong = true;
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		} while (isWrong);

		return result;
	}
}
